package com.fjwt.gz.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class ApiStatisticsLogger {
    // 静态单例实例
    private static final ApiStatisticsLogger INSTANCE = new ApiStatisticsLogger();
    // 存储接口统计数据（线程安全）
    private final ConcurrentHashMap<String, Stats> statsMap = new ConcurrentHashMap<>();
    // 定时任务调度器
    private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public static final Logger apiStatisticsLogger = LoggerFactory.getLogger("apiStatistics");

    // 私有构造方法（单例模式）
    private ApiStatisticsLogger() {
        // 启动定时任务，每分钟打印一次
        scheduler.scheduleAtFixedRate(this::printStatistics, 0, 1, TimeUnit.MINUTES);
    }

    // 获取单例实例
    public static ApiStatisticsLogger getInstance() {
        return INSTANCE;
    }

    // 记录接口请求（线程安全）
    public void logRequest(String apiId, long durationMs) {
        statsMap.compute(apiId, (key, stats) -> {
            if (stats == null) {
                stats = new Stats();
            }
            stats.add(durationMs);
            return stats;
        });
    }

    // 打印统计信息并重置计数器
    private void printStatistics() {
        statsMap.forEach((apiId, stats) -> {
            Stats.Snapshot snapshot = stats.snapshotAndReset();
            if (snapshot.count == 0) return;

            double avg = (double) snapshot.totalTime / snapshot.count;
            apiStatisticsLogger.info(String.format("[%s] 请求次数：%d | 总耗时：%dms | 最大耗时：%dms | 平均耗时：%.2fms%n",
                    apiId, snapshot.count, snapshot.totalTime, snapshot.maxTime, avg));
        });
    }

    // 停止定时任务（可选）
    public void shutdown() {
        scheduler.shutdown();
    }

    // 内部统计类（线程安全）
    private static class Stats {
        private final AtomicLong count = new AtomicLong(0);
        private final AtomicLong totalTime = new AtomicLong(0);
        private final AtomicLong maxTime = new AtomicLong(0);

        public void add(long duration) {
            count.incrementAndGet();
            totalTime.addAndGet(duration);
            maxTime.accumulateAndGet(duration, Math::max);
        }

        // 快照并重置（原子操作）
        public Snapshot snapshotAndReset() {
            return new Snapshot(
                    count.getAndSet(0),
                    totalTime.getAndSet(0),
                    maxTime.getAndSet(0)
            );
        }

        // 快照数据对象
        public static class Snapshot {
            public final long count;
            public final long totalTime;
            public final long maxTime;

            public Snapshot(long count, long totalTime, long maxTime) {
                this.count = count;
                this.totalTime = totalTime;
                this.maxTime = maxTime;
            }
        }
    }

    // 测试示例
    public static void main(String[] args) throws InterruptedException {
        // 模拟多线程调用
        ExecutorService executor = Executors.newFixedThreadPool(4);
        for (int i = 0; i < 100; i++) {
            executor.submit(() -> {
                ApiStatisticsLogger logger = ApiStatisticsLogger.getInstance();
                logger.logRequest("UserAPI", ThreadLocalRandom.current().nextInt(50, 200));
            });
        }
        executor.shutdown();
        executor.awaitTermination(5, TimeUnit.SECONDS);
    }
}